package com.canyou.exception;

import com.canyou.api.ResponseBO;
import com.canyou.enums.ErrorCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MissingServletRequestParameterException;

import static com.canyou.api.ResponseBO.*;

/**
 * 认证服务器异常处理类
 *
 * @author cgz
 * @date 2019-05-01
 */
@Slf4j
@Component
public class CysWebResponseExceptionTranslator implements WebResponseExceptionTranslator {

    public static final String BAD_MSG = "坏的凭证";

    @Override
    public ResponseEntity translate(Exception e) {
        log.warn(e.getMessage(), e);
        String errMsg = e.getMessage();
        ResponseBO responseResult;
        if (errMsg != null && errMsg.equals(BAD_MSG)) {
            // 这里不要提示`用户名不存在`, 而应该提示`用户名或密码错误`
            responseResult = error(ErrorCodeEnum.INVALID_GRANT);
        } else if (e instanceof InvalidGrantException) {
            String invalidRefreshMsg = "Invalid refresh token";
            if (errMsg != null && errMsg.contains(invalidRefreshMsg)) {
                responseResult = invalidRefreshToken();
            } else {
                responseResult = error(ErrorCodeEnum.INVALID_GRANT);
            }
        } else if (e instanceof UsernameNotFoundException) {
            responseResult = error(ErrorCodeEnum.INVALID_GRANT);
        } else if (e instanceof InsufficientAuthenticationException) {
            responseResult = invalidAccessToken();
        } else if (e instanceof InternalAuthenticationServiceException) {
            responseResult = unAuthorized();
        } else if (e instanceof InvalidTokenException) {
            responseResult = invalidRefreshToken();
        } else if (e instanceof MissingServletRequestParameterException) {
            responseResult = illegal(e.getMessage());
        } else if (e instanceof CysBusinessException) {
            CysBusinessException err = (CysBusinessException) e;
            responseResult = fail(err.getCode(), err.getMsg());
        } else {
            responseResult = fail(e.getLocalizedMessage());
        }
        return ResponseEntity.status(HttpStatus.OK).body(responseResult);
    }
}